/**
 * Copy from n2o.min.js
 * 
 * modified sth.
 */


 const Blob = require("cross-blob");
 globalThis.Blob = Blob;


function atom(o) {
    return {
        type: "Atom",
        value: o,
        toString: function() {
            return this.value
        }
    }
}
function bin(o) {
    return {
        type: "Binary",
        value: o,
        toString: function() {
            return "<<'" + this.value + "'>>"
        }
    }
}
function tuple() {
    return {
        type: "Tuple",
        value: arguments,
        toString: function() {
            for (var s = "", i = 0; this.value.length > i; i++)
                "" !== s && (s += ","),
                s += this.value[i];
            return "{" + s + "}"
        }
    }
}
function dec(S) {
    return decode(ltoa(new Uint8Array(S)))
}
function enc(s) {
    for (var ori = encode(s), buf = new Uint8Array(new ArrayBuffer(ori.length)), i = 0; buf.length > i; i++)
        buf[i] = ori.charCodeAt(i);
    /** GT: nodejs 不需要这个 return new Blob([buf.buffer]) */
    return buf
}
function itoa(x) {
    return String.fromCharCode(x)
}
function ltoa(a) {
    for (var i = 0, s = ""; a.length > i; i++)
        s += itoa(a[i]);
    return s
}
function itol(Int, Length) {
    var isNegative, OriginalInt, i, Rem, s = "";
    for (isNegative = 0 > Int,
    isNegative && (Int = -1 * Int),
    OriginalInt = Int,
    i = 0; Length > i; i++)
        Rem = Int % 256,
        isNegative && (Rem = 255 - Rem),
        s = String.fromCharCode(Rem) + s,
        Int = Math.floor(Int / 256);
    if (Int > 0)
        throw "BERT: Range: " + OriginalInt;
    return s
}
function ltoi(S, Length) {
    var isNegative, i, n, Num = 0;
    for (isNegative = S.charCodeAt(0) > 128,
    i = 0; Length > i; i++)
        n = S.charCodeAt(i),
        isNegative && (n = 255 - n),
        Num = 0 === Num ? n : 256 * Num + n;
    return isNegative && (Num = -1 * Num),
    Num
}
function ltobi(S, Count) {
    var isNegative, i, n, Num = 0;
    for (isNegative = 1 === S.charCodeAt(0),
    S = S.substring(1),
    i = Count - 1; i >= 0; i--)
        n = S.charCodeAt(i),
        Num = 0 === Num ? n : 256 * Num + n;
    return isNegative ? -1 * Num : Num
}
function encode(o) {
    return BERT + en_inner(o)
}
function en_inner(Obj) {
    if (void 0 === Obj)
        return NIL;
    var func = "en_" + typeof Obj;
    return eval(func)(Obj)
}
function en_string(Obj) {
    return STR + itol(Obj.length, 2) + Obj
}
function en_boolean(Obj) {
    return Obj ? en_inner(atom("true")) : en_inner(atom("false"))
}
function en_number(Obj) {
    var isi = 0 === Obj % 1;
    return isi ? isi && Obj >= 0 && 256 > Obj ? SINT + itol(Obj, 1) : INT + itol(Obj, 4) : en_float(Obj)
}
function en_float(Obj) {
    for (var s = Obj.toExponential(); 31 > s.length; )
        s += ZERO;
    return FLOAT + s
}
function en_object(Obj) {
    return "Atom" === Obj.type ? en_atom(Obj) : "Binary" === Obj.type ? en_bin(Obj) : "Tuple" === Obj.type ? en_tuple(Obj) : -1 !== ("" + Obj.constructor).indexOf("Array") ? en_array(Obj) : en_associative_array(Obj)
}
function en_atom(Obj) {
    return ATOM + itol(Obj.value.length, 2) + Obj.value
}
function en_bin(Obj) {
    return BINARY + itol(Obj.value.length, 4) + Obj.value
}
function en_tuple(Obj) {
    var i, s = "";
    for (s += 256 > Obj.value.length ? TUPLE + itol(Obj.value.length, 1) : LTUPLE + itol(Obj.value.length, 4),
    i = 0; Obj.value.length > i; i++)
        s += en_inner(Obj.value[i]);
    return s
}
function en_array(Obj) {
    var i, s = LIST + itol(Obj.length, 4);
    for (i = 0; Obj.length > i; i++)
        s += en_inner(Obj[i]);
    return s += NIL
}
function en_associative_array(Obj) {
    var key, Arr = [];
    for (key in Obj)
        Obj.hasOwnProperty(key) && Arr.push(tuple(atom(key), Obj[key]));
    return en_array(Arr)
}
function decode(S) {
    if (S[0] !== BERT)
        throw "Not a valid BERT.";
    var Obj = de_inner(S.substring(1));
    if ("" !== Obj.rest)
        throw "Invalid BERT.";
    return Obj.value
}
function de_inner(S) {
    var Type = S[0];
    switch (S = S.substring(1),
    Type) {
    case SATOM:
        de_atom(S, 1);
    case ATOM:
        return de_atom(S, 2);
    case BINARY:
        return de_bin(S);
    case SINT:
        return de_small_integer(S);
    case INT:
        return de_integer(S);
    case FLOAT:
        return de_float(S);
    case SBIG:
        return de_big(S, 1);
    case LBIG:
        return de_big(S, 4);
    case STR:
        return de_string(S);
    case LIST:
        return de_list(S);
    case TUPLE:
        return de_tuple(S, 1);
    case NIL:
        return de_nil(S);
    default:
        throw "BERT: " + S.charCodeAt(0)
    }
}
function de_atom(S, Count) {
    var Size, Value;
    return Size = ltoi(S, Count),
    S = S.substring(Count),
    Value = S.substring(0, Size),
    "true" === Value ? Value = !0 : "false" === Value && (Value = !1),
    {
        value: atom(Value),
        rest: S.substring(Size)
    }
}
function de_bin(S) {
    var Size = ltoi(S, 4);
    return S = S.substring(4),
    {
        value: bin(S.substring(0, Size)),
        rest: S.substring(Size)
    }
}
function de_big(S, Count) {
    var Size, Value;
    return Size = ltoi(S, Count),
    S = S.substring(Count),
    Value = ltobi(S, Size),
    {
        value: Value,
        rest: S.substring(Size + 1)
    }
}
function de_integer(S) {
    var Value = ltoi(S, 4);
    return S = S.substring(4),
    {
        value: Value,
        rest: S
    }
}
function de_small_integer(S) {
    var Value = S.charCodeAt(0);
    return S = S.substring(1),
    {
        value: Value,
        rest: S
    }
}
function de_float(S) {
    var Size = 31;
    return {
        value: parseFloat(S.substring(0, Size)),
        rest: S.substring(Size)
    }
}
function de_string(S) {
    var Size = ltoi(S, 2);
    return S = S.substring(2),
    {
        value: S.substring(0, Size),
        rest: S.substring(Size)
    }
}
function de_list(S) {
    var Size, i, El, LastChar, Arr = [];
    for (Size = ltoi(S, 4),
    S = S.substring(4),
    i = 0; Size > i; i++)
        El = de_inner(S),
        Arr.push(El.value),
        S = El.rest;
    if (LastChar = S[0],
    LastChar !== NIL)
        throw "BERT: Wrong NIL.";
    return S = S.substring(1),
    {
        value: Arr,
        rest: S
    }
}
function de_tuple(S, Count) {
    var Size, i, El, Arr = [];
    for (Size = ltoi(S, Count),
    S = S.substring(Count),
    i = 0; Size > i; i++)
        El = de_inner(S),
        Arr.push(El.value),
        S = El.rest;
    return {
        value: tuple(Arr),
        rest: S
    }
}
function de_nil(S) {
    return {
        value: [],
        rest: S
    }
}
function querySourceRaw(Id) {
    var val, el = document.getElementById(Id);
    if (!el)
        return "";
    switch (el.getAttribute("type")) {
    case "fieldset":
        val = document.querySelector("#" + Id + " :checked"),
        val = val ? val.value : "";
        break;
    case "radio":
    case "checkbox":
        val = el.checked ? el.value : "";
        break;
    case "date":
        val = getErlDate(el);
        break;
    default:
        var edit = el.getAttribute("contenteditable");
        val = edit && "true" === edit ? el.innerHTML : el.value
    }
    return val
}
function querySource(Id) {
    var qs = querySourceRaw(Id);
    return "" == qs ? bin("") : utf8_toByteArray(qs)
}
function getErlDate(el) {
    var val = /^(\d{4})-(\d{1,2})-(\d{1,2})$/.exec(el.value);
    if (null != val) {
        var uDate = new Date(parseInt(val[1]),parseInt(val[2]) - 1,parseInt(val[3]));
        uDate.getMonth() + 1 == parseInt(val[2]) && uDate.getDate() == parseInt(val[3]) && uDate.getFullYear() == parseInt(val[1]) ? (val[2] = 9 > uDate.getMonth() ? "0" + (uDate.getMonth() + 1) : uDate.getMonth() + 1,
        val[3] = 10 > uDate.getDate() ? "0" + uDate.getDate() : uDate.getDate(),
        val = "{" + uDate.getFullYear() + "," + val[2] + "," + val[3] + "}") : val = ""
    } else
        val = "";
    return val
}
function utf8_toByteArray(str) {
    var byteArray = [];
    if (void 0 !== str && null !== str)
        for (var i = 0; str.length > i; i++)
            if (127 >= str.charCodeAt(i))
                byteArray.push(str.charCodeAt(i));
            else
                for (var h = encodeURIComponent(str.charAt(i)).substr(1).split("%"), j = 0; h.length > j; j++)
                    byteArray.push(parseInt(h[j], 16));
    return byteArray
}
function utf8_fromByteArray(byteArray, separator) {
    if (byteArray === void 0 || 0 == byteArray.byteLength)
        return "";
    separator = separator !== void 0 ? separator : ",";
    for (var dataView = new DataView(byteArray), s = "" + dataView.getUint8(0), i = 1; byteArray.byteLength > i; i++)
        s = s + separator + ("" + dataView.getUint8(i));
    return s
}
function utf8_decode(utftext) {
    for (var string = "", i = c = c1 = c2 = 0; utftext.length > i; )
        c = utftext.charCodeAt(i),
        128 > c ? (string += String.fromCharCode(c),
        i++) : c > 191 && 224 > c ? (c2 = utftext.charCodeAt(i + 1),
        string += String.fromCharCode((31 & c) << 6 | 63 & c2),
        i += 2) : (c2 = utftext.charCodeAt(i + 1),
        c3 = utftext.charCodeAt(i + 2),
        string += String.fromCharCode((15 & c) << 12 | (63 & c2) << 6 | 63 & c3),
        i += 3);
    return string
}

function qi(name) {
    return document.getElementById(name)
}
function qs(name) {
    return document.querySelector(name)
}
function qn(name) {
    return document.createElement(name)
}
function validateSources(list) {
    /** GT: 这里修改了源码 */
    return true
}
function validateLength(e, minlength, maxlength) {
    var field = e.detail;
    return field.length >= minlength && maxlength >= field.length
}
function validateMin(e, min) {
    var field = e.detail
      , re = /^\d{1,}$/;
    return console.debug(re.test(field)),
    re.test(field) ? parseFloat(field) > min : !1
}
BERT = itoa(131),
SATOM = itoa(115),
ATOM = itoa(100),
BINARY = itoa(109),
SINT = itoa(97),
INT = itoa(98),
FLOAT = itoa(99),
STR = itoa(107),
LIST = itoa(108),
SBIG = itoa(110),
LBIG = itoa(111),
TUPLE = itoa(104),
LTUPLE = itoa(105),
NIL = itoa(106),
ZERO = itoa(0);


module.exports = {atom, bin, enc, tuple, dec, utf8_fromByteArray, utf8_toByteArray, validateSources, validateMin, validateLength, qi, qn, qs}


